package com.txby.platformApi.component.web;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.boot.autoconfigure.security.SecurityProperties.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.jck.mybatis.util.IdWorker;
import com.jck.poi.excelkit.ExcelCommonViewUtil;
import com.jck.poi.excelkit.ExcelFieldHeader;
import com.jck.poi.excelkit.ExcelFieldUtil;
import com.jck.tools.ChkUtil;
import com.jck.tools.MD5Util;
import com.jck.tools.Times;
import com.jck.tools.easyui.ResponseUtils;
import com.jck.tools.util.FileHandleUtil;
import com.txby.pf.modules.oss.cloud.OSSFactory;
import com.txby.pf.modules.oss.entity.SysOssEntity;
import com.txby.pf.modules.sys.entity.SysDeptEntity;
import com.txby.platformApi.data.excel.ProductDeviceInitExcel;
import com.txby.platformCore.data.CommonApiModelMapExt;
import com.txby.platformCore.entity.ProductDeviceInit;
import com.txby.platformCore.entity.ProductDeviceInitLot;
import com.txby.platformCore.entity.TxbySysApiUser;

/**
 * 产品信息初始化
 */
@Controller
@RequestMapping("/pro/deviceInitExcel")
public class ProductDeviceInitExcelController extends CommonController {

	public Map mapData = null;
	public static Map userToken = null;
	public boolean isToken = true;
	public Class clz;
	public String paramName = "excelFile";
	public static String uploadFilePath = "/upload/";
	public String fileName = "";
	public String fileFullName = "";
	public String fileDownPath = "";
	public String moduleName = "";
	public String filePath = "";
	public String singleName = Times.getDateToStringHHmmssSSS(new Date());
	public boolean isXSS = true;
	public boolean isNewAnnotation = true;
	public boolean isData = false;
	public static String userId = null;
	public String operation = null;
	public String content = null;
	public String moduleUrl = "";
	public String commonUrl = "/pro/deviceInitExcel";
	public User user = null;
	public static String createUser = "";
	public static String lastUpdateUser = "";
	public static Date createTime = new Date();
	public static Date lastUpdateTime = new Date();
	private static String state = "0";

	@RequestMapping(value = { "/exportDeviceInitExcel" }, method = {
			org.springframework.web.bind.annotation.RequestMethod.POST })
	public ModelAndView exportDeviceInitExcel(Model model, HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		this.clz = ProductDeviceInitExcel.class;
		this.moduleName = "导出产品设备初始化绑定";
		this.moduleUrl = (this.commonUrl + "/exportDeviceInitExcel");
		this.operation = this.moduleName;
		if (this.isData) {
			this.content = "数据导出";
		} else {
			this.content = "模版导出";
		}
		this.fileName = (this.moduleName + "exportDeviceInitExcel" + this.singleName + this.content);
		ModelAndView mv = null;
		String sql = "";
		try {
			Map<String, Object> dataMap = new HashMap();
			dataMap.put("dataList", new ArrayList());

			String tplPath = "/excelTpl/ProductDeviceInit_tpl.xlsx";
			if (!this.isXSS) {
				tplPath = "/excelTpl/ProductDeviceInit_tpl.xlsx";
			}
			List<List<String>> validationListName = new ArrayList();
			List<String> deptNameList = getSubDeptIdListString(1);
			List<String> sickNameList = getSubDeptIdListString(2);
			validationListName.add(deptNameList);
			validationListName.add(sickNameList);
			List objs = new ArrayList();
			if (this.isData) {
				sql = "SELECT t.deviceSN  as deviceSN,t.bedNO bedNO,(select concat(p.name,'_',p.dept_id) from sys_dept p where p.dept_id = t.deptId) as deptName,(select  concat(p.name,'_',p.dept_id) from sys_dept p where p.dept_id = t.sickAreaNO) as sickAreaName FROM t_txby_productDeviceInit t order by t.updateTime desc ";
				objs = this.mBaseDao.findAll(sql, ProductDeviceInitExcel.class, null);
				/*
				 * ExcelViewUtil erv = new ExcelViewUtil(this.fileName,
				 * this.fileName, this.isNewAnnotation, this.isXSS, false, clzs,
				 * null, tplPath, dataListObjs, sheetIndexs);
				 */
			}
			ExcelCommonViewUtil erv = new ExcelCommonViewUtil(fileName, fileName, isNewAnnotation, isXSS, true, clz,
					validationListName, tplPath, objs);
			mv = new ModelAndView(erv, dataMap);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return mv;
	}

	@RequestMapping(value = { "/importDeviceInitExcel" }, method = {
			org.springframework.web.bind.annotation.RequestMethod.POST })
	public ModelAndView importDeviceInitExcel(@RequestParam("excelFile") MultipartFile excelFile, Model model,
			HttpServletRequest request, HttpServletResponse response, Writer wr) throws Exception {
		this.clz = ProductDeviceInitExcel.class;
		this.moduleName = "产品设备初始化绑定";
		this.fileName = (this.moduleName + "importDeviceInitExcel" + this.singleName + "可能数据重复或不规范错误（请进行修正）");
		ModelAndView mv = null;
		this.moduleUrl = (this.commonUrl + "/importDeviceInitExcel");
		this.operation = this.moduleName;
		this.content = "数据导入:import_addCount|fail_failCount";
		List<Object> excelList = new ArrayList();
		try {
			String message = "文件扩展名或格式不正确,不是excel文件";
			String url = "dataError";
			Map map = FileHandleUtil.getfileUploadInputStreamMap(request, this.paramName);
			if (ChkUtil.isEmptyAllObject(map)) {
				wr.write(ResponseUtils.buildResultJson(Boolean.valueOf(false), message, url));
				return null;
			}
			if (!((Boolean) map.get("result")).booleanValue()) {
				wr.write(ResponseUtils.buildResultJson(map));
				return null;
			}
			InputStream in = (InputStream) map.get("inputStream");

			String tplPath = "/excelTpl/ProductDeviceInit_tpl.xlsx";
			if (!this.isXSS) {
				tplPath = "/excelTpl/ProductDeviceInit_tpl.xlsx";
			}

			String sql = "";
			Map<String, Object> dataMap = new HashMap();
			dataMap.put("dataList", new ArrayList());

			List<List<String>> validationListName = new ArrayList();
			List<String> deptNameList = getSubDeptIdListString(1);
			List<String> sickNameList = getSubDeptIdListString(2);
			validationListName.add(deptNameList);
			validationListName.add(sickNameList);
			List objs = new ArrayList();

			excelList = ExcelFieldUtil.getInstance().readExcel2ObjsByInputStream(in, this.clz, 0);
			List<Object> nolList = new ArrayList();
			List<ExcelFieldHeader> headList = ExcelFieldUtil.getInstance().getHeaderList(this.clz);
			message = "";
			int index = 0;
			boolean isNull;
			for (Object obj : excelList) {
				index++;
				Object oldObj = obj;
				isNull = true;
				boolean isDataType = true;
				boolean isFieldLength = true;
				for (int j = 0; j < headList.size(); j++) {
					ExcelFieldHeader efh = (ExcelFieldHeader) headList.get(j);
					String mn = efh.getFieldName();
					Object o = PropertyUtils.getProperty(obj, mn);
					if ((efh.isTZW()) && (ChkUtil.isEmpty(o))) {
						isNull = false;
						if (!ChkUtil.isEmpty(message)) {
							break;
						}
						message = "详细信息-第" + (nolList.size() + 3) + "行，字段名：" + efh.getTitle() + " ，须必填或数据类型不符";

						break;
					}
					if ((!ChkUtil.isEmpty(o)) && (!ChkUtil.getDataTypeSet(o).contains(efh.getFieldType()))) {
						isDataType = false;
						if (!ChkUtil.isEmpty(message)) {
							break;
						}
						message = "详细信息-第" + (nolList.size() + 3) + "行，字段名：" + efh.getTitle() + " ，数据类型可能须为数字";

						break;
					}
					if ((!ChkUtil.isEmpty(o)) && (!ChkUtil.isOKLength(o, efh.getFieldLength()))) {
						isFieldLength = false;
						if (!ChkUtil.isEmpty(message)) {
							break;
						}
						message = "详细信息-第" + (nolList.size() + 3) + "行，字段名：" + efh.getTitle() + " ，数据字段不能超过"
								+ efh.getFieldLength() + "位";

						break;
					}
				}
				if (!isNull) {
					nolList.add(oldObj);
				} else if (!isDataType) {
					nolList.add(oldObj);
				} else if (!isFieldLength) {
					nolList.add(oldObj);
				} else {
					ProductDeviceInitExcel px = new ProductDeviceInitExcel();
					BeanUtils.copyProperties(px, obj);
					ProductDeviceInitExcel pbe = (ProductDeviceInitExcel) obj;
					ProductDeviceInit pb = new ProductDeviceInit();
					Map params = new HashMap();
					params.put("deviceSN", pbe.getDeviceSN());
					sql = "select * from  " + this.mBaseDao.tableName(ProductDeviceInit.class)
							+ " where deviceSN=#{pojo.deviceSN}";
					ProductDeviceInit pdiOld = (ProductDeviceInit) this.mBaseDao.findBySqlUniqueObject(sql,
							ProductDeviceInit.class, params);
					if (pdiOld == null)// 判断业务数据正确性
					{

						String deptId = pbe.getDeptName().split("_")[1];
						String sickAreaNO = pbe.getSickAreaName().split("_")[1];
						String sickAreaName = pbe.getSickAreaName().split("_")[0];
						sql = " SELECT * from t_txby_productDeviceInit  WHERE deptId=" + deptId + " and sickAreaNO="
								+ sickAreaNO + " and bedNO='" + pbe.getBedNO() + "'";
						pdiOld = (ProductDeviceInit) this.mBaseDao.findBySqlUniqueObject(sql, ProductDeviceInit.class,
								null);
						List<SysDeptEntity> sickAreaNo = getSubDeptIdList(2);
						if (pdiOld == null) {
							pbe.setDeptId(deptId);
							pbe.setCreater(getUserId().toString());
							pbe.setUpdater(getUserId().toString());
							pbe.setSickAreaName(sickAreaName);
							pbe.setSickAreaNO(sickAreaNO);
							BeanUtils.copyProperties(pb, pbe);// 复制实体保存
							this.mBaseDao.saveObject(pb);

							ProductDeviceInitLot pdil = new ProductDeviceInitLot();
							BeanUtils.copyProperties(pdil, pb);
							this.mBaseDao.saveObject(pdil);
						} else {

							if (ChkUtil.isEmpty(message)) {
								message = "详细信息-第" + (nolList.size() + 3) + "行，字段名：此医院、病区、床位号和设备SN已绑定了 ，此数据重复";
							}
							nolList.add(px);

						}

						sql = "select * from " + this.mBaseDao.tableName(TxbySysApiUser.class) + "  where userName='"
								+ pbe.getDeviceSN() + "'";
						// db1e81c178f84c11f8dd19fa2b99c3f0
						TxbySysApiUser gau = (TxbySysApiUser) this.mBaseDao.findBySqlUniqueObject(sql,
								TxbySysApiUser.class, null);
						if (gau != null) {
							/*
							 * gau.setPassWord(MD5Util.getMD5ofStr(
							 * "db1e81c178f84c11f8dd19fa2b99c3f0", 2));
							 * this.mBaseDao.updateObject(gau);
							 * gau.setUpdateTime(new Date());
							 */
						} else {
							gau = new TxbySysApiUser();
							gau.setUserName(pbe.getDeviceSN());
							gau.setPassWord(MD5Util.getMD5ofStr("db1e81c178f84c11f8dd19fa2b99c3f0", 2));
							this.mBaseDao.saveObject(gau);

						}
					} else {
						if (ChkUtil.isEmpty(message)) {
							message = "详细信息-第" + (nolList.size() + 3) + "行，字段名：设备SN编号 ，已经绑定组织，此数据重复，请删除原绑定或在系统中单一修改即可";
						}
						nolList.add(px);
					}
				}
			}
			if (nolList.size() != 0) {
				if (this.isXSS) {
					this.filePath = (this.filePath + this.fileName + ".xlsx");
					this.fileFullName = (this.fileName + ".xlsx");
				} else {
					this.filePath = (this.filePath + this.fileName + ".xls");
					this.fileFullName = (this.fileName + ".xls");
				}

				// FileOutputStream fot = new FileOutputStream(new
				// File(this.filePath));
				// 下面添加有效性
				List newObjs = new ArrayList<>();
				// 添加失败的数据
				newObjs.addAll(nolList);
				/*
				 * ExcelErrorUtil erv = new ExcelErrorUtil(this.fileName,
				 * this.fileName, this.isNewAnnotation, this.isXSS, false, clzs,
				 * null, tplPath, dataListObjs, sheetIndexs, fot);
				 */
				// ExcelCommonViewUtil erv = new ExcelCommonViewUtil(fileName,
				// fileName, isNewAnnotation, isXSS, true, clz,
				// validationListName, tplPath, newObjs,fot);
				ExcelCommonViewUtil erv = new ExcelCommonViewUtil(fileName, fileName, isNewAnnotation, isXSS, true, clz,
						validationListName, tplPath, newObjs);

				Workbook wb = ExcelFieldUtil.getInstance().exportObj2ExcelByTemplateNewReturnWorkbook(tplPath, newObjs,
						clz, validationListName);
				this.fileFullName = getOssUploadUrl(wb, this.fileFullName);
				wr.write(
						ResponseUtils.buildResultJson(
								Boolean.valueOf(false), "本次成功导入数据 " + (excelList.size() - nolList.size()) + " 条,失败数据 "
										+ nolList.size() + " 条;可能是数据重复或不规范错误,点击下载查看错误数据并修正;" + message,
								this.fileFullName));
				// mv = new ModelAndView(erv, dataMap);
			} else if (excelList.size() > 0) {
				wr.write(ResponseUtils.buildResultJson(Boolean.valueOf(true), "导入成功", this.fileFullName));
			} else {
				wr.write(ResponseUtils.buildResultJson(Boolean.valueOf(false), "无数据或模版数据选择有误,请重试", "dataError"));
			}
			this.content = this.content.replaceAll("import_addCount", "import_" + (excelList.size() - nolList.size()));
			this.content = this.content.replaceAll("fail_failCount", "fail_" + nolList.size());
		} catch (Exception e) {
			wr.write(ResponseUtils.buildResultJson(Boolean.valueOf(false), "系统异常,请联系系统管理员", "dataError"));
			e.printStackTrace();
			this.content = this.content.replaceAll("import_addCount", "import_0");
			this.content = this.content.replaceAll("fail_failCount", "fail_0");
		}
		return mv;

	}

	@ModelAttribute
	public void initModelAttribute(HttpServletRequest request, HttpServletResponse response, String isData) {
		String realpath = request.getSession().getServletContext().getRealPath(uploadFilePath);// 给予存储路径
		this.filePath = realpath + "/";
		if (!ChkUtil.isEmpty(isData) && isData.equals("1")) {
			this.isData = true;
		} else {
			this.isData = false;
		}

	}

	@RequestMapping("/download")
	public ModelAndView download(String fileName, HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		response.setContentType("text/html;charset=utf-8");
		request.setCharacterEncoding("UTF-8");
		java.io.BufferedInputStream bis = null;
		java.io.BufferedOutputStream bos = null;
		String ctxPath = request.getSession().getServletContext().getRealPath(uploadFilePath) + "/";
		String downLoadPath = ctxPath + fileName;
		try {
			long fileLength = new File(downLoadPath).length();
			response.setContentType("application/x-msdownload;");
			response.setHeader("Content-disposition",
					"attachment; filename=" + new String(fileName.getBytes("utf-8"), "ISO8859-1"));
			response.setHeader("Content-Length", String.valueOf(fileLength));
			bis = new BufferedInputStream(new FileInputStream(downLoadPath));
			bos = new BufferedOutputStream(response.getOutputStream());
			byte[] buff = new byte[2048];
			int bytesRead;
			while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
				bos.write(buff, 0, bytesRead);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (bis != null)
				bis.close();
			if (bos != null)
				bos.close();
		}
		return null;
	}

	public String getOssUploadUrl(Workbook wb, String fileName) throws IOException {
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		wb.write(os);
		// ByteArray bytes = os.toByteArray();
		InputStream in = new ByteArrayInputStream(os.toByteArray());
		String path = "/images/" + IdWorker.get32UUID() + fileName;
		// 上传文件
		String url = OSSFactory.build().upload(in, path);
		// 保存文件信息
		SysOssEntity ossEntity = new SysOssEntity();
		ossEntity.setUrl(url);
		ossEntity.setCreateDate(new Date());
		this.sysOssService.save(ossEntity);
		System.out.println(url);
		return url;
	}
}
